#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

#include <nibble/nibble.h>

#define output(fmtstr, args...) \
  (fprintf(stderr, PROGNAME ":%s: " fmtstr "\n", __func__, ##args))

static int verbose_flag;


static void print_usage(void)
{
  printf("There are 2 modes of usage depending if transmitting or receiving.\n");
  printf("To transmit: nibble --schema <file> --xml <file> --time <seconds>\n");
  printf("To receive: nibble --schema <file> --time <seconds>\n");
  exit (EXIT_SUCCESS);
}


int tx(const char *schema_file, const char *xml_file, int seconds)
{

  nibbleContext *nc = NULL;
  xmlDocPtr doc = NULL;

  int bytes;
  
  nc = init_nibble(schema_file);

  if ((doc = packedobjects_new_doc(xml_file)) == NULL) {
    printf("did not find .xml file\n");
    exit (EXIT_FAILURE);
  }
  
  bytes = tx_nibble(nc, doc, seconds);
  if (verbose_flag) output("tx %d bytes", bytes);

  xmlFreeDoc(doc);
  free_nibble(nc);
  
  return (EXIT_SUCCESS);
}

int rx(const char *schema_file, int seconds)
{

  nibbleContext *nc = NULL;
  xmlDocPtr doc = NULL;


  nc = init_nibble(schema_file);
  doc = rx_nibble(nc, seconds);
  packedobjects_dump_doc(doc);
  xmlFreeDoc(doc);
  free_nibble(nc);
  
  return (EXIT_SUCCESS);
}

int main(int argc, char **argv)
{
  int c;
  const char *schema_file = NULL;
  const char *xml_file = NULL;
  int seconds = 0;
  
  while(1) {
    static struct option long_options[] =
      {
        {"verbose", no_argument,       &verbose_flag, 1},
        {"help",  no_argument, 0, 'h'},
        {"schema",  required_argument, 0, 's'},
        {"xml",  required_argument, 0, 'x'},
        {"time",  required_argument, 0, 't'},
        {0, 0, 0, 0}
      };
    int option_index = 0;
    
    c = getopt_long (argc, argv, "hs:x:t:?", long_options, &option_index);
    
    if (c == -1) break;
    
    switch (c)
      {
      case 0:
        if (long_options[option_index].flag != 0) break;
        printf ("option %s", long_options[option_index].name);
        if (optarg) printf (" with arg %s", optarg);
        printf ("\n");
        break;

      case 'h':
        print_usage();
        break;
        
      case 's':
        schema_file = optarg;
        break;
        
      case 'x':
        xml_file = optarg;
        break;
        
      case 't':
        seconds = atoi(optarg);
        break;
        
      case '?':
        print_usage();
        break;
        
      default:
        abort ();
      }
  }

  
  if ((schema_file) && (xml_file) && (seconds)) tx(schema_file, xml_file, seconds);
  else if ((schema_file) && (seconds)) rx(schema_file, seconds);
  else print_usage();
  
  return (EXIT_SUCCESS);
}
